package org.platform.lwc.redis.config;


import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.platform.lwc.redis.factory.lettuce.ObtainLettuceConnectionFactory;
import org.platform.lwc.redis.properties.MyRedisProperties;
import org.platform.lwc.redis.seriation.RedisKeySerializer;
import org.platform.lwc.redis.seriation.RedisObjectSerializer;
import org.platform.lwc.redis.utils.RedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * RedisTemplate 配置
 *
 * @author lwc
 */
@EnableCaching
@Configuration
@AutoConfigureBefore(RedisAutoConfiguration.class)
public class RedisTemplateConfiguration {

    @Autowired
    private RedisProperties redisProperties;

    @Bean(name = "redisTemplate")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        RedisKeySerializer redisKeySerializer = new RedisKeySerializer();
        RedisSerializer redisObjectSerializer = new RedisObjectSerializer();
        redisTemplate.setKeySerializer(redisKeySerializer);// key的序列化类型 这里统一封装前缀
        redisTemplate.setHashKeySerializer(redisKeySerializer);// key的序列化类型这里统一封装前缀
        redisTemplate.setValueSerializer(redisObjectSerializer);// value的序列化类型
        redisTemplate.setHashValueSerializer(redisObjectSerializer);// value的序列化类型
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * @Description: 根据配置生成对应的LettuceConnectionFactory 对象
     * @Author: lwc
     * @Date: 2021/5/20 14:19
     */
    @Bean
    public LettuceConnectionFactory lettuceConnectionFactory() {
        return new ObtainLettuceConnectionFactory().getObtainLettuceConnection(redisProperties);

    }
    /**
     * @Description: redisTemplate 这个类初始化了才会初始化这个对象
     * @Author: lwc
     * @Date: 2021/5/20 10:26
     */
    @Bean
    @ConditionalOnBean(name = "redisTemplate")
    public RedisUtil RedisUtil() {
        return new RedisUtil();
    }

    /**
     * @Description: Spring使用缓存方式
     * @Author: lwc
     * @Date: 2021/5/20 10:26
     */
    @Bean
    public CacheManager cacheManager(LettuceConnectionFactory lettuceConnectionFactory ) {

        RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig();
        redisCacheConfiguration = redisCacheConfiguration.entryTtl(Duration.ofMinutes(30L)) // 设置缓存的默认超时时间：30分钟
                .disableCachingNullValues() // 如果是空值，不缓存
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.string())) // 设置key序列化器
                .serializeValuesWith(
                        RedisSerializationContext.SerializationPair.fromSerializer(RedisSerializer.java())); // 设置value序列化器
        return RedisCacheManager.builder(RedisCacheWriter.nonLockingRedisCacheWriter(lettuceConnectionFactory))
                .cacheDefaults(redisCacheConfiguration).build();
    }

}
